package com.szholly.pro.watergas_server.common.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import com.szholly.pro.watergas_server.common.cache.RedisEhcacheUtil;
import org.apache.log4j.Logger;

import lrq.common.MyLog;
import lrq.common.PropertiesUnit;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;

public class RedisDbExecute {
	
	/**
	 * 用于站点状态的获取
	 */
	private static JedisPool stationStatusPool = null;
	/**
	 * 用于业务数据的获取
	 */
	private static JedisPool businessDataPool = null;
	static SimpleDateFormat defaultSf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	static Logger log;
	
	private static void initPool(){
		log = MyLog.getLogger("RedisLog");
		initPool1();
		initPool2();
	}
	
	/**
	 * 初始化站点状态信息redis
	 */
	private static void initPool1(){
		JedisPoolConfig config = new JedisPoolConfig();
		 // 控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
	      // 如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
	      config.setMaxIdle(500);
	      // 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
	      config.setMaxIdle(1000 * 60);
	      // 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
	      config.setMaxWaitMillis(1000 * 100);
	      // 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
	      config.setTestOnBorrow(true);
	      // pool = new JedisPool(config, "192.168.0.121", 6379, 100000);
	      String host = PropertiesUnit.getValue("redishost_stationStatus");
	      stationStatusPool = new JedisPool(config,host, 6379, 10000);
	}
	
	/**
	 * 初始化业务信息redis
	 */
	private static void initPool2(){
		JedisPoolConfig config = new JedisPoolConfig();
		 // 控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
	      // 如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
	      config.setMaxIdle(500);
	      // 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
	      config.setMaxIdle(1000 * 60);
	      // 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
	      config.setMaxWaitMillis(1000 * 100);
	      // 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
	      config.setTestOnBorrow(true);
	      // pool = new JedisPool(config, "192.168.0.121", 6379, 100000);
	      String host = PropertiesUnit.getValue("redishost_businessData");
	      businessDataPool = new JedisPool(config,host, 6379, 10000);
	}
	
	/**
	 * 根据key路由redis
	 * stationInfo开头的key是站点信息的redis
	 * 其他的是业务数据的key
	 * @param key
	 * @return
	 */
	private static Jedis getDb(String key) {
		
		if(stationStatusPool == null || businessDataPool == null){
			initPool();
		}
		
		if(key.startsWith("stationInfo")){
			return stationStatusPool.getResource();
		}
		else{
			return businessDataPool.getResource();
		}
	}
	
	/**
	 * 获取站点信息的redis
	 * @return
	 */
	public static Jedis getStationStatusDB() {
		return getDb("stationInfo");
	}
	
	/**
	 * 获取业务信息redis
	 * @return
	 */
	public static Jedis getBusinessDataDB() {
		return getDb("sysdict");
	}
	
	public static void returnResource(Jedis jedis){
		try {
			stationStatusPool.returnResourceObject(jedis);
		} catch (Exception e) {
			try {
				businessDataPool.returnResourceObject(jedis);
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
	
	public static void setMapString(String key,String fieldName,String value){
		Jedis jedis = getDb(key);
		try {
			jedis.hset(key, fieldName, value);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static void setMap(String key,HashMap<String, String> value){
		Jedis jedis = getDb(key);
		try {
			jedis.hmset(key, value);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static void setMapDate(String key,String fieldName,Date value){
		Jedis jedis = getDb(key);
		try {
			jedis.hset(key, fieldName, defaultSf.format(value));
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static void setDate(String key,Date value){
		Jedis jedis = getDb(key);
		try {
			jedis.set(key, defaultSf.format(value));
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static void setString(String key,String value,Pipeline pipeLine){
		Jedis jedis = null;
		try {
			if(pipeLine != null){
				pipeLine.set(key, value);
			}
			else{
				jedis = getDb(key);
				jedis.set(key, value);
			}
			
			RedisEhcacheUtil.getInstance().set(key, value);
		} 
		catch(Exception e){
			
		}
		finally {
			if(jedis != null){
				returnResource(jedis);
			}
			
		}
	}
	
	public static void setString(String key,String value){
		setString(key, value, null);
	}
	
	public static void setString(String key,String value,int second){
		Jedis jedis = getDb(key);
		try {
			jedis.set(key, value);
			jedis.expire(key, second);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static void delValue(String key){
		Jedis jedis = getDb(key);
		try {
			jedis.del(key);
			RedisEhcacheUtil.getInstance().delete(key);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
	}
	
	public static String getMapString(String key,String fieldName){
		Jedis jedis = getDb(key);
		String value = null;
		try {
			value = jedis.hget(key, fieldName);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return value;
	};
	public static String getString(String key){
		Jedis jedis = getDb(key);
		String value = null;
		try {
		  value = jedis.get(key);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return value;
	};
	
	public static Integer getMapInt(String key,String fieldName){
		Jedis jedis = getDb(key);
		Integer intValue = null;
		try {
			String value = jedis.hget(key, fieldName);
			intValue = toInt(value);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return intValue;
	}
	
	public static Integer getInt(String key){
		Jedis jedis = getDb(key);
		Integer intValue = null;
		try {
			String value = jedis.get(key);
			intValue = toInt(value);
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return intValue;
	}
	
	public static Double getMapDouble(String key,String fieldName){
		Jedis jedis = getDb(key);
		Double doubleValue = null;
		try {
			String value = jedis.hget(key, fieldName);
			doubleValue = toDouble(value) ;
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return doubleValue;
	}
	
	public static Double getDouble(String key){
		Jedis jedis = getDb(key);
		Double doubleValue = null;
		try {
			String value = jedis.get(key);
			doubleValue = toDouble(value) ;
		} 
		catch(Exception e){
			
		}
		finally {
			returnResource(jedis);
		}
		return doubleValue;
	}
	
	public static Date getMapDate(String key,String fieldName,String pattern){
		Jedis jedis = getDb(key);
		Date dateValue = null;
		try {
			String value = jedis.hget(key, fieldName);
			dateValue = toDate(value, pattern);
		} 
		catch(Exception e){
			e.printStackTrace();
			
		}
		finally {
			returnResource(jedis);
		}
		return dateValue;
	}
	
	public static Date getDate(String key,String pattern){
		Jedis jedis = getDb(key);
		Date dateValue = null;
		try {
			String value = jedis.get(key);
			dateValue = toDate(value, pattern);
		} 
		catch(Exception e){
			e.printStackTrace();
			
		}
		finally {
			returnResource(jedis);
		}
		return dateValue;
	}
	
	public static Date getDate(String key){
		Jedis jedis = getDb(key);
		Date dateValue = null;
		try {
			String value = jedis.get(key);
			if(value == null){
				return null;
			}
			dateValue = defaultSf.parse(value);
		} 
		catch(Exception e){
			e.printStackTrace();
			
		}
		finally {
			returnResource(jedis);
		}
		return dateValue;
	}
	
	public static Integer toInt(String value){
		if(value == null){
			return null;
		}
		Integer intValue = null;
		try {
			intValue = Integer.parseInt(value);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return intValue;
	}
	
	public static Double toDouble(String value){
		if(value == null){
			return null;
		}
		Double doubleValue = null ;
		try {
			doubleValue = Double.parseDouble(value);
		} catch (Exception e) {
			return null;
		}
		return doubleValue;
	}
	
	public static Date toDate(String value,String pattern){
		if(value == null){
			return null;
		}
		SimpleDateFormat sf = null;
		
		if(pattern == null){
			sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}
		else{
			sf = new SimpleDateFormat(pattern);
		}
		
		Date dateValue = null;
		try {
			dateValue = sf.parse(value);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dateValue;
	}
	
	/**
	 * 模糊匹配key
	 * gislin
	 * 2016年3月17日
	 * @param parentKey
	 * @return
	 */
	public static Set<String> queryKeys(String parentKey){
		Jedis jedis = getDb(parentKey);
		Set<String> treeKeys = new TreeSet<>();
		try {
			Set<String> keys = jedis.keys(parentKey);
			for(String key : keys){
				treeKeys.add(key);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}		
		finally {
			returnResource(jedis);
		}
		return treeKeys;
	}
	
	public static HashMap<String, Response<String>> pipeLineGet(List<String> keys){
		Pipeline pipeLine = getDb(keys.get(0)).pipelined();
		HashMap<String, Response<String>> result = new HashMap<>();
		for(String key : keys){
			result.put(key, pipeLine.get(key));
		}
		return result;
	}
	
	/**
	 * 模糊删除key
	 * gislin
	 * 2016年3月24日
	 * @param keyPattern
	 */
	public static void deleteKeys(String keyPattern){
		Set<String> keys = queryKeys(keyPattern);
		if(keys != null){
			for(String key : keys){
				delValue(key);
			}
		}
	}
}
